package com.skyd.core.android.game;

import java.util.ArrayList;

import android.graphics.Canvas;
import android.graphics.Matrix;

/**
 * 游戏中精灵的基类
 * 
 * @author SkyD
 * 
 */
public abstract class GameSpirit extends GameNodeObject implements
		IGameVerticalCapsuleHitTest,IGameRectHitTest,ICurrentFrameNumberSupport {

	/**
	 * 初始值为null。 功能注释：精灵名称
	 */
	private String _Name = null;

	/**
	 * 获取Name。 功能注释：精灵名称
	 * 
	 * @return 当前的String类型的值
	 */
	public String getName() {
		return _Name;
	}

	/**
	 * 设置Name。 功能注释：精灵名称
	 * 
	 * @param value
	 *            要设置的String类型值
	 */
	public void setName(String value) {
		_Name = value;
	}

	/**
	 * 设置Name为其默认值(null)。 功能注释：精灵名称
	 */
	public void setNameToDefault() {
		setName(null);
	}

	/**
	 * 初始值为0。 功能注释：所在图层，较大的值会在顶端
	 */
	private float _Level = 0;

	/**
	 * 获取Level。 功能注释：所在图层，较大的值会在顶端
	 * 
	 * @return 当前的float类型的值
	 */
	public float getLevel() {
		return _Level;
	}

	/**
	 * 设置Level。 功能注释：所在图层，较大的值会在顶端
	 * 
	 * @param value
	 *            要设置的float类型值
	 */
	public void setLevel(float value) {
		_Level = value;
		onLevelChanged(value);
	}

	/**
	 * 设置图层在目标精灵之上
	 * 
	 * @param target
	 *            目标精灵
	 */
	public void setLevelAbove(GameSpirit target) {
		setLevel(target.getLevel() + 0.00000001f);
	}

	/**
	 * 设置图层在目标精灵之下
	 * 
	 * @param target
	 *            目标精灵
	 */
	public void setLevelBelow(GameSpirit target) {
		setLevel(target.getLevel() - 0.00000001f);
	}
	
	/**
	 * 设置图层在目标层之上
	 * 
	 * @param target
	 *            目标层
	 */
	public void setLevelAbove(float target) {
		setLevel(target + 0.00000001f);
	}

	/**
	 * 设置图层在目标层之下
	 * 
	 * @param target
	 *            目标层
	 */
	public void setLevelBelow(float target) {
		setLevel(target - 0.00000001f);
	}

	/**
	 * 设置Level为其默认值(0)。 功能注释：所在图层，较大的值会在顶端
	 */
	public void setLevelToDefault() {
		setLevel(0);
	}

	/**
	 * 当精灵所在图层修改时触发
	 */
	public interface OnLevelChangedListener {
		/**
		 * 触发LevelChanged事件时执行的方法
		 * 
		 * @param sender
		 *            触发LevelChanged事件的对象
		 */
		public abstract void OnLevelChangedEvent(Object sender, float value);
	}

	/**
	 * LevelChanged事件监听器列表。当精灵所在图层修改时触发
	 */
	private ArrayList<OnLevelChangedListener> _LevelChangedListenerList = null;

	/**
	 * 增加一个LevelChanged事件的监听器，返回是否成功增加。事件功能注释：当精灵所在图层修改时触发
	 * 
	 * @param listener
	 *            LevelChanged事件监听器对象
	 * @return 是否成功增加。如果该监听器对象已存在，则返回false。
	 */
	public boolean addOnLevelChangedListener(OnLevelChangedListener listener) {
		if (_LevelChangedListenerList == null)
			_LevelChangedListenerList = new ArrayList<OnLevelChangedListener>();
		else if (_LevelChangedListenerList.contains(listener))
			return false;
		_LevelChangedListenerList.add(listener);
		return true;
	}

	/**
	 * 移除一个LevelChanged事件的监听器，返回是否成移除。事件功能注释：当精灵所在图层修改时触发
	 * 
	 * @param listener
	 *            LevelChanged事件监听器对象
	 * @return 是否成功移除。如果该监听器对象不存在，则返回false。
	 */
	public boolean removeOnLevelChangedListener(OnLevelChangedListener listener) {
		if (_LevelChangedListenerList == null
				|| !_LevelChangedListenerList.contains(listener))
			return false;
		_LevelChangedListenerList.remove(listener);
		return true;
	}

	/**
	 * 清空所有LevelChanged事件的监听器。事件功能注释：当精灵所在图层修改时触发
	 */
	public void clearOnLevelChangedListeners() {
		if (_LevelChangedListenerList != null)
			_LevelChangedListenerList.clear();
	}

	/**
	 * 当精灵所在图层修改时触发
	 */
	protected void onLevelChanged(float value) {
		if (_LevelChangedListenerList != null)
			for (OnLevelChangedListener listener : _LevelChangedListenerList) {
				listener.OnLevelChangedEvent(this, value);
			}
	}

	@Override
	protected void operateCanvasForParentAbsoluteSize(Canvas c) {
		// 精灵类不根据根对象尺寸做填充操作
		if(getParent() instanceof GameRootObject)return;
		super.operateCanvasForParentAbsoluteSize(c);
	}
	
	

	@Override
	protected void operateMatrixForParentAbsoluteSize(Matrix m) {
		// 精灵类不根据根对象尺寸做填充操作
		if(getParent() instanceof GameRootObject)return;
		super.operateMatrixForParentAbsoluteSize(m);
	}

	@Override
	public float getVerticalCapsuleHitTestHeight() {
		float v = getSize().getY();
		return Math.max(v/2, v-getVerticalCapsuleHitTestRadius());
	}

	@Override
	public float getVerticalCapsuleHitTestRadius() {
		return getSize().getX() / 2;
	}

	@Override
	public float getVerticalCapsuleHitTestX() {
		return getPosition().getX() + getPositionOffset().getX()
				+ getSize().getX() / 2;
	}

	@Override
	public float getVerticalCapsuleHitTestY() {
		float v = getPosition().getY() + getPositionOffset().getY();
		return Math
				.min(v + getSize().getY() / 2, v + getVerticalCapsuleHitTestRadius());
	}

	@Override
	public float getRectHitTestBottom() {
		return getRectHitTestTop()+getSize().getY();
	}

	@Override
	public float getRectHitTestLeft() {
		return getPosition().getX() + getPositionOffset().getX();
	}

	@Override
	public float getRectHitTestRight() {
		return getRectHitTestLeft()+getSize().getX();
	}

	@Override
	public float getRectHitTestTop() {
	return	getPosition().getY() + getPositionOffset().getY();
	}
	
	/**
	 * 获取CurrentFrameNumber。
	 * 功能注释：场景的当前帧计数
	 * @return 当前的long类型的值
	 */
		public  long getCurrentFrameNumber() {
			return ((ICurrentFrameNumberSupport)getParent()).getCurrentFrameNumber();
		}
}
